﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Douban.Core;
using System.Windows.Input;
using Douban.Api.Broadcast;
using Douban.Api.User;
using Microsoft.Practices.Composite.Presentation.Commands;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Composite.Events;
using Douban.Core.Events;
using System.Collections.ObjectModel;
using Douban.Modules.Broadcast.Views;
using Douban.Api;
using System.ComponentModel;
using System.Diagnostics;

namespace Douban.Modules.Broadcast.ViewModels
{
    public class BroadcastItemViewModel : ObservableObject
    {
        private DoubanService _doubanService;
        private Author _author;

        public BroadcastItemViewModel(Miniblog miniblog)
        {
            _doubanService = ServiceLocator.Current.GetInstance<DoubanService>();

            Miniblog = miniblog;
            _author = miniblog.Author ?? 
                new Author(_doubanService.UserService.CurrentUser);
        }

        private void UpdateComments(bool force = false)
        {
            if(!IsSaying) return;

            if (Miniblog.CommentsCount == 0 && !force) return;

            Comments = new ObservableCollection<CommentItemViewModel>();

            CommentFeed commentFeed = _doubanService.BroadcastService.GetMiniblogComments(Id, 1, CommentsCount);
            foreach (Comment c in commentFeed.Comments)
                Comments.Add(new CommentItemViewModel(c));
        }

        public BroadcastItemView View { get; set; }

        private Miniblog _miniblog;

        public Miniblog Miniblog 
        {
            get { return _miniblog; }
            set 
            {
                _miniblog = value;
                if (_miniblog != null)
                {
                    PublishedTime = _miniblog.PublishedTime;
                    CommentsCount = _miniblog.CommentsCount;
                    UpdateComments();
                }
            }
        }

        private IEventAggregator _eventAggregator;

        private IEventAggregator EventAggregator
        {
            get
            {
                if (_eventAggregator == null)
                    _eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();

                return _eventAggregator;
            }
        }

        public int MaxLength
        {
            get { return 140; }
        }
        
        public string UserId
        {
            get { return _author.Id; }
        }

        public string IconUri
        {
            get { return _author.IconUri; }
        }	

        public string Name
        {
            get { return _author.Name; }
        }

        
        private DateTime _publishedTime;

        public DateTime PublishedTime
        {
            get { return _publishedTime; }
            set
            {
                if (_publishedTime != value)
                {
                    _publishedTime = value;
                    NotifyPropertyChanged("PublishedTime");
                }
            }
        }

        public string MiniblogText
        {
            get { return Miniblog.HtmlContent; }
        }
        
        public string Id
        {
            get { return Miniblog.Id; }
        }
        
        public string Category
        {
            get { return Miniblog.Category; }
        }

        public bool IsSaying
        {
            get 
            {
                if (Category == null) return false;
                return Category == "saying";
            }
        }
        
        private string _replyText;

        public string ReplyText
        {
            get { return _replyText; }
            set
            {
                if (_replyText != value)
                {
                    _replyText = value;
                    NotifyPropertyChanged("ReplyText");
                }
            }
        }
        
        private int _commentsCount;

        public int CommentsCount
        {
            get { return _commentsCount; }
            set
            {
                if (_commentsCount != value)
                {
                    _commentsCount = value;
                    NotifyPropertyChanged("CommentsCount");
                }
            }
        }
					
        private ObservableCollection<CommentItemViewModel> _comments;

        public ObservableCollection<CommentItemViewModel> Comments
        {
            get { return _comments; }
            set
            {
                if (_comments != value)
                {
                    _comments = value;
                    NotifyPropertyChanged("Comments");
                }
            }
        }
				
        private ICommand _replyCommand;

        public ICommand ReplyCommand
        {
            get
            {
                if (_replyCommand == null)
                    _replyCommand = new DelegateCommand<object>(obj => ReplySaying());

                return _replyCommand;
            }
        }

        private ICommand _expandCommentCommand;

        public ICommand ExpandCommentCommand
        {
            get
            { 
                if(_expandCommentCommand == null)
                    _expandCommentCommand = new DelegateCommand<object>(obj => View.ExpandComments());

                return _expandCommentCommand;
            }
        }
        
        private ICommand _checkInfoCommand;

        public ICommand CheckInfoCommand
        {
            get
            {
                if (_checkInfoCommand == null)
                    _checkInfoCommand = new DelegateCommand<object>(obj => CheckInfo());

                return _checkInfoCommand;
            }
        }

        private ICommand _goToDoubanPageCommand;

        public ICommand GoToDoubanPageCommand
        {
            get
            {
                if (_goToDoubanPageCommand == null)
                    _goToDoubanPageCommand = new DelegateCommand<object>(obj => Process.Start(_author.DoubanPage));

                return _goToDoubanPageCommand;
            }
        }

        private void CheckInfo()
        {
            EventAggregator.GetEvent<CheckInfoEvent>().Publish(UserId);
        }

        private void ReplySaying()
        {
            string content = ReplyText;
            ReplyText = string.Empty;

            if (string.IsNullOrEmpty(content)) return;
            
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += (sender, e) =>
                _doubanService.BroadcastService.ReplyMiniblog(Id, content);
            worker.RunWorkerCompleted += (sender, e) => UpdateComments(true);

            worker.RunWorkerAsync();
        }
    }
}
